package com.example.api.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.api.vo.CarPaginateVO;
import com.example.api.vo.CarTotalVO;
import com.example.api.dto.CarAddDTO;
import com.example.api.dto.CarEditQuantityDTO;
import com.example.api.mapper.CarMapper;
import com.example.api.mapper.GoodsSpecMapper;
import com.example.api.po.CarTotalPO;
import com.example.api.service.CarService;
import com.example.common.bo.PageParamBO;
import com.example.common.exception.ServiceException;
import com.example.common.po.CarPO;
import com.example.common.po.GoodsSpecPO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

/**
 *
 */
@Service("apiCarServiceImpl")
public class CarServiceImpl extends ServiceImpl<CarMapper, CarPO>
        implements CarService {

    @Autowired
    private HttpServletRequest httpServletRequest;
    @Autowired
    private CarMapper carMapper;
    @Autowired
    private GoodsSpecMapper goodsSpecMapper;

    @Resource
    DataSourceTransactionManager dataSourceTransactionManager;

    @Resource
    TransactionDefinition transactionDefinition;
    /**
     * 获取购物车分页
     *
     * @param pageParamBO
     * @return
     */
    public IPage getJoinPaginateById(PageParamBO pageParamBO) {
        Integer userId = (Integer) httpServletRequest.getSession().getAttribute("id");
        return carMapper.getJoinPaginateById(
                new Page<>(pageParamBO.getPageIndex(), pageParamBO.getPageSize()),
                userId
        ).convert(po -> {
            CarPaginateVO vo = new CarPaginateVO();
            BeanUtils.copyProperties(po, vo);
            return vo;
        });
    }

    /**
     * 用户添加商品到购物车
     *
     * @param carAddDto
     * @return
     */
    @Override
    public CarTotalVO add(CarAddDTO carAddDto) {
        //开启事务
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            GoodsSpecPO data = goodsSpecMapper.selectOne(
                    new QueryWrapper<GoodsSpecPO>()
                            .lambda()
                            .eq(GoodsSpecPO::getStatus, 1)
                            .eq(GoodsSpecPO::getGoodsId, carAddDto.getGoodsId())
                            .eq(GoodsSpecPO::getSkuCode, carAddDto.getSkuCode())
                            .last("FOR UPDATE")
            );
            if (Objects.isNull(data)) {
                throw new ServiceException("找不到资源", 104);
            }
            if (!data.getStatus()) {
                throw new ServiceException("商品已下架", 106);
            }
            if (data.getStoreCount() == 0) {
                throw new ServiceException("商品库存不足", 106);
            }
            // 判断是否已经添加
            Integer userId = (Integer) httpServletRequest.getSession().getAttribute("id");
            CarPO check = carMapper.selectOne(
                    new QueryWrapper<CarPO>()
                            .lambda()
                            .eq(CarPO::getUserId, userId)
                            .eq(CarPO::getGoodsId, carAddDto.getGoodsId())
                            .eq(CarPO::getSkuCode, carAddDto.getSkuCode())
            );
            Integer result = 0;
            if (Objects.isNull(check)) {
                CarPO po = new CarPO();
                BeanUtils.copyProperties(carAddDto, po);
                po.setUserId(userId);
                po.setChecked(true);
                result = carMapper.insert(po);
            } else {
                CarPO po = new CarPO();
                BeanUtils.copyProperties(carAddDto, po);
                result = carMapper.update(
                        po,
                        new UpdateWrapper<CarPO>()
                                .lambda()
                                .setSql("quantity = quantity+" + carAddDto.getQuantity())
                );
            }
            if (result.equals(0)) {
                throw new ServiceException("添加失败", 106);
            }
            dataSourceTransactionManager.commit(transactionStatus);
            return getCartTotal();
        }catch (ServiceException e){
            dataSourceTransactionManager.rollback(transactionStatus);
            throw new ServiceException(e.getMessage(), 106);
        }catch (Exception e){
            dataSourceTransactionManager.rollback(transactionStatus);
            throw new ServiceException(e.getMessage(), 106);
        }
    }

    /**
     * 修改购物车商品数量
     *
     * @param carEditQuantityDto
     * @return
     */
    @Override
    public CarTotalVO editQuantity(CarEditQuantityDTO carEditQuantityDto) {
        Integer userId = (Integer) httpServletRequest.getSession().getAttribute("id");
        CarPO po = carMapper.selectOne(
                new QueryWrapper<CarPO>()
                        .lambda()
                        .eq(CarPO::getUserId, userId)
                        .eq(CarPO::getCarId, carEditQuantityDto.getCarId())
        );
        if (Objects.isNull(po)) {
            throw new ServiceException("找不到资源", 104);
        }
        Integer result = carMapper.update(
                new UpdateWrapper<CarPO>()
                        .lambda()
                        .eq(CarPO::getUserId, userId)
                        .eq(CarPO::getCarId, carEditQuantityDto.getCarId())
                        .set(CarPO::getQuantity, carEditQuantityDto.getQuantity())
        );
        if (result.equals(0)) {
            throw new ServiceException("修改失败", 106);
        }
        return getCartTotal();
    }

    /**
     * 修改选中状态
     *
     * @param carId
     * @return
     */
    @Override
    public CarTotalVO editChecked(Integer carId) {
        Integer userId = (Integer) httpServletRequest.getSession().getAttribute("id");
        CarPO po = carMapper.selectOne(
                new QueryWrapper<CarPO>()
                        .lambda()
                        .eq(CarPO::getUserId, userId)
                        .eq(CarPO::getCarId, carId)
        );
        if (Objects.isNull(po)) {
            throw new ServiceException("找不到资源", 104);
        }
        Integer result = carMapper.update(
                new UpdateWrapper<CarPO>()
                        .lambda()
                        .eq(CarPO::getUserId, userId)
                        .eq(CarPO::getCarId, carId)
                        .setSql("checked = !checked")
        );
        if (result.equals(0)) {
            throw new ServiceException("更新失败", 106);
        }
        return getCartTotal();
    }

    /**
     * 获取数量
     *
     * @return
     */
    @Override
    public Integer getCount() {
        Integer userId = (Integer) httpServletRequest.getSession().getAttribute("id");
        return carMapper.getCount(userId);
    }

    /**
     * 获取购物车统计
     *
     * @return
     */
    @Override
    public CarTotalVO getCartTotal() {
        Integer userId = (Integer) httpServletRequest.getSession().getAttribute("id");
        CarTotalPO po = carMapper.getCartTotal(userId);
        CarTotalVO vo = new CarTotalVO();
        BeanUtils.copyProperties(po, vo);
        return vo;
    }

    /**
     * 删除购物车商品
     *
     * @param carId
     * @return
     */
    @Override
    public CarTotalVO delete(Integer carId) {
        CarPO po = carMapper.selectOne(
                new QueryWrapper<CarPO>()
                        .lambda()
                        .eq(CarPO::getUserId, httpServletRequest.getSession().getAttribute("id"))
                        .eq(CarPO::getCarId, carId)
        );
        if (Objects.isNull(po)) {
            throw new ServiceException("找不到资源", 104);
        }
        Integer result = carMapper.deleteById(carId);
        if (result.equals(0)) {
            throw new ServiceException("删除失败", 106);
        }
        return getCartTotal();
    }

    /**
     * 修改全部选中状态
     *
     * @param checked
     * @return
     */
    @Override
    public CarTotalVO changeAll(Boolean checked) {
        Integer userId = (Integer) httpServletRequest.getSession().getAttribute("id");
        carMapper.update(
                new UpdateWrapper<CarPO>()
                        .lambda()
                        .eq(CarPO::getUserId, userId)
                        .set(CarPO::getChecked, checked)
        );
        return getCartTotal();
    }

    /**
     * 批量删除
     *
     * @param carIds
     * @return
     */
    @Override
    public CarTotalVO deleteBatch(List carIds) {
        Integer userId = (Integer) httpServletRequest.getSession().getAttribute("id");
        carMapper.delete(new QueryWrapper<CarPO>().lambda().eq(CarPO::getUserId, userId).in(CarPO::getCarId, carIds));
        return getCartTotal();
    }
}




